
package cinema.v1_5.service;

import cinema.v1_5.model.*;

import java.sql.*;
import java.time.LocalDateTime;
import java.util.*;

public class CinemaService {

    /* ---------- 初始化（首次运行自动插入） ---------- */
    public void initData() {
        if (count("t_user") > 0) return; // 已初始化过

        insertUser(new User(UUID.randomUUID().toString(), "admin",
                "123456", "ADMIN", "13800000000", LocalDateTime.now()));
        insertUser(new User(UUID.randomUUID().toString(), "manager1",
                "123456", "MANAGER", "13900000000", LocalDateTime.now()));
        insertUser(new User(UUID.randomUUID().toString(), "front1",
                "123456", "FRONT", "13700000000", LocalDateTime.now()));

        insertHall(new Hall(UUID.randomUUID().toString(), "黄金厅", 8, 10));
        insertHall(new Hall(UUID.randomUUID().toString(), "白银厅", 10, 12));
        insertHall(new Hall(UUID.randomUUID().toString(), "翡翠厅", 7, 8));
        insertHall(new Hall(UUID.randomUUID().toString(), "钻石厅", 7, 8));
        insertHall(new Hall(UUID.randomUUID().toString(), "宝石厅", 8, 9));

        List<Movie> ms = List.of(
                new Movie(UUID.randomUUID().toString(), "泰坦尼克号",
                        "詹姆斯·卡梅隆", "莱昂纳多 / 凯特", "爱情悲剧", 194, 9.5),
                new Movie(UUID.randomUUID().toString(), "流浪地球",
                        "郭帆", "吴京 / 屈楚萧", "科幻灾难", 125, 8.0)
        );
        ms.forEach(this::insertMovie);

        List<Hall> hs = listHalls();
        List<Movie> movies = listMovies();
        if (!movies.isEmpty() && !hs.isEmpty()) {
            insertSession(new Session(UUID.randomUUID().toString(),
                    movies.get(0).getId(), hs.get(0).getId(),
                    LocalDateTime.of(2025, 8, 20, 19, 30), 45.0));
            insertSession(new Session(UUID.randomUUID().toString(),
                    movies.get(1).getId(), hs.get(1).getId(),
                    LocalDateTime.of(2025, 8, 20, 20, 0), 40.0));
        }
    }

    /* ---------- 通用计数 ---------- */
    private int count(String table) {
        String sql = "SELECT COUNT(*) FROM " + table;
        try (Connection c = DBUtil.getConn();
             PreparedStatement ps = c.prepareStatement(sql);
             ResultSet rs = ps.executeQuery()) {
            if (rs.next()) return rs.getInt(1);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /* ---------- 用户相关 ---------- */
    public boolean login(String username, String password) {
        String sql = "SELECT 1 FROM t_user WHERE username=? AND password=?";
        try (Connection c = DBUtil.getConn();
             PreparedStatement ps = c.prepareStatement(sql)) {
            ps.setString(1, username);
            ps.setString(2, password);
            try (ResultSet rs = ps.executeQuery()) {
                return rs.next();
            }
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    public List<User> listUsers() {
        List<User> list = new ArrayList<>();
        String sql = "SELECT id,username,password,role,phone,reg_time FROM t_user";
        try (Connection c = DBUtil.getConn();
             PreparedStatement ps = c.prepareStatement(sql);
             ResultSet rs = ps.executeQuery()) {
            while (rs.next()) {
                list.add(new User(rs.getString(1), rs.getString(2),
                        rs.getString(3), rs.getString(4),
                        rs.getString(5), rs.getTimestamp(6).toLocalDateTime()));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    private void insertUser(User u) {
        String sql = "INSERT INTO t_user(id,username,password,role,phone,reg_time) VALUES (?,?,?,?,?,?)";
        try (Connection c = DBUtil.getConn();
             PreparedStatement ps = c.prepareStatement(sql)) {
            ps.setString(1, u.getId());
            ps.setString(2, u.getUsername());
            ps.setString(3, u.getPassword());
            ps.setString(4, u.getRole());
            ps.setString(5, u.getPhone());
            ps.setTimestamp(6, Timestamp.valueOf(u.getRegTime()));
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /* ---------- Movie ---------- */
    public List<Movie> listMovies() {
        List<Movie> list = new ArrayList<>();
        String sql = "SELECT id,name,director,actors,plot,duration,score FROM t_movie";
        try (Connection c = DBUtil.getConn();
             PreparedStatement ps = c.prepareStatement(sql);
             ResultSet rs = ps.executeQuery()) {
            while (rs.next()) {
                list.add(new Movie(rs.getString(1), rs.getString(2),
                        rs.getString(3), rs.getString(4),
                        rs.getString(5), rs.getInt(6), rs.getDouble(7)));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    private void insertMovie(Movie m) {
        String sql = "INSERT INTO t_movie(id,name,director,actors,plot,duration,score) VALUES (?,?,?,?,?,?,?)";
        try (Connection c = DBUtil.getConn();
             PreparedStatement ps = c.prepareStatement(sql)) {
            ps.setString(1, m.getId());
            ps.setString(2, m.getName());
            ps.setString(3, m.getDirector());
            ps.setString(4, m.getActors());
            ps.setString(5, m.getPlot());
            ps.setInt(6, m.getDuration());
            ps.setDouble(7, m.getScore());
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /* ---------- Hall ---------- */
    public List<Hall> listHalls() {
        List<Hall> list = new ArrayList<>();
        String sql = "SELECT id,name,rows,cols FROM t_hall";
        try (Connection c = DBUtil.getConn();
             PreparedStatement ps = c.prepareStatement(sql);
             ResultSet rs = ps.executeQuery()) {
            while (rs.next()) {
                list.add(new Hall(rs.getString(1), rs.getString(2),
                        rs.getInt(3), rs.getInt(4)));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    private void insertHall(Hall h) {
        String sql = "INSERT INTO t_hall(id,name,rows,cols) VALUES (?,?,?,?)";
        try (Connection c = DBUtil.getConn();
             PreparedStatement ps = c.prepareStatement(sql)) {
            ps.setString(1, h.getId());
            ps.setString(2, h.getName());
            ps.setInt(3, h.getRows());
            ps.setInt(4, h.getCols());
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /* ---------- Session ---------- */
    public List<Session> listSessions() {
        List<Session> list = new ArrayList<>();
        String sql = "SELECT id,movie_id,hall_id,start_time,price FROM t_session";
        try (Connection c = DBUtil.getConn();
             PreparedStatement ps = c.prepareStatement(sql);
             ResultSet rs = ps.executeQuery()) {
            while (rs.next()) {
                list.add(new Session(rs.getString(1), rs.getString(2),
                        rs.getString(3), rs.getTimestamp(4).toLocalDateTime(),
                        rs.getDouble(5)));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    private void insertSession(Session s) {
        String sql = "INSERT INTO t_session(id,movie_id,hall_id,start_time,price) VALUES (?,?,?,?,?)";
        try (Connection c = DBUtil.getConn();
             PreparedStatement ps = c.prepareStatement(sql)) {
            ps.setString(1, s.getId());
            ps.setString(2, s.getMovieId());
            ps.setString(3, s.getHallId());
            ps.setTimestamp(4, Timestamp.valueOf(s.getStartTime()));
            ps.setDouble(5, s.getPrice());
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}